import 'dart:convert';

import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';

class Cryptor {
  static String aes256Encrypt(Map encryptMap, String key,
      {required String iv}) {
    final _key = Key.fromUtf8(key);
    final _iv = IV.fromUtf8(iv);
    AESMode mode = AESMode.cbc;

    final encrypter = Encrypter(AES(_key, mode: mode));

    String encryptString = '{}';
    if (encryptMap.length > 0) {
      encryptString = jsonEncode(encryptMap);
    }

    final encrypted = encrypter.encrypt(encryptString, iv: _iv);
    return encrypted.base64;
  }

  static String aes256Decrypt(String encrypted, String key,
      {required String iv}) {
    final _key = Key.fromUtf8(key);
    final _iv = IV.fromUtf8(iv);
    AESMode mode = AESMode.cbc;

    final encrypter = Encrypter(AES(_key, mode: mode));
    String decrypted = encrypter.decrypt64(encrypted, iv: _iv);
    return decrypted;
  }
}

extension $String_Cryptor on String {
  String md5String({int length = 32}) {
    if (length != 32 && length != 16) {
      assert(false, 'Invalid md5 length.');
    }
    String md5String = md5.convert(utf8.encode(this)).toString();
    if (length == 16) {
      md5String = md5String.md5_16bitString;
    }
    return md5String;
  }

  String get md5_16bitString {
    String md5_16 = '';
    int len = 4;
    for (int i = 0; i < this.length / len; ++i) {
      if (i % 2 == 0) {
        md5_16 += this.substring(i * len, len * i + len);
      }
    }

    return md5_16;
  }
}
